<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      #canvas {
        background-color: black;
        height: 800px;
        width: 800px;
      }
    </style>
  </head>
  <body>
    <div id="canvas"></div>
    <script type="importmap">
      {
        "imports": {
          "three": "../node_modules/three/build/three.module.js",
          "three/addons/": "../node_modules/three/examples/jsm/utils/"
        }
      }
    </script>
    <script type="module">
      import * as THREE from '../node_modules/three/build/three.module.js';
      import * as BufferGeometryUtils from 'three/addons/BufferGeometryUtils.js';
      import ThreeBase from './ThreeBase.js';
      class MyEarth extends ThreeBase {
        constructor() {
          super();
          //   this.isAxis = true;
          this.isStats = true;
          this.initCameraPos = [37, 50, 100];
        }

        animateAction() {}

        createChart(that) {
          //开启renderer阴影
          this.renderer.shadowMap.enabled = true;
          this.renderer.shadowMap.type = THREE.PCFSoftShadowMap;

          //设置光照
          const light = new THREE.AmbientLight(0xffffff, 0.6); // soft white light
          this.scene.add(light);
          //夜晚光照蓝色
          const dirLight = new THREE.DirectionalLight(0x0000ff, 3);
          dirLight.position.set(50, 50, 50);
          this.scene.add(dirLight);

          //投射阴影设置
          dirLight.castShadow = true;
          dirLight.shadow.camera.top = 100;
          dirLight.shadow.camera.bottom = -100;
          dirLight.shadow.camera.left = -100;
          dirLight.shadow.camera.right = 100;
          dirLight.shadow.camera.near = 1;
          dirLight.shadow.camera.far = 200;
          dirLight.shadow.mapSize.set(1024, 1024);

          const pg = new THREE.PlaneGeometry(100, 100);
          const pm = new THREE.MeshStandardMaterial({
            color: new THREE.Color('gray'),
            side: THREE.FrontSide
          });
          const plane = new THREE.Mesh(pg, pm);
          plane.rotateX(-Math.PI * 0.5);
          plane.receiveShadow = true;
          this.scene.add(plane);

          //随机生成建筑
          this.geometries = [];
          const helper = new THREE.Object3D();
          for (let i = 0; i < 100; i++) {
            const h = Math.round(Math.random() * 15) + 5;
            const x = Math.round(Math.random() * 50);
            const y = Math.round(Math.random() * 50);
            helper.position.set((x % 2 ? -1 : 1) * x, h * 0.5, (y % 2 ? -1 : 1) * y);
            const geometry = new THREE.BoxGeometry(5, h, 5);
            helper.updateWorldMatrix(true, false);
            geometry.applyMatrix4(helper.matrixWorld);
            this.geometries.push(geometry);
          }
          const mergedGeometry = BufferGeometryUtils.mergeGeometries(this.geometries, false);
          const texture = new THREE.TextureLoader().load('assets/image.jpg');
          texture.wrapS = texture.wrapT = THREE.MirroredRepeatWrapping;
          const material = new THREE.MeshStandardMaterial({ map: texture });
          const cube = new THREE.Mesh(mergedGeometry, material);
          cube.castShadow = true;
          cube.receiveShadow = true;
          this.scene.add(cube);

          this.shaders = [];
          const vertexShader1 = `uniform float uSize;
              varying vec2 vUv;
              void main() {`;
          const vertexShader2 = `#include <fog_vertex>
                      vUv=position.xz/uSize;`;
          const vertexShader3 = `#include <fog_vertex>
                        vUv=vec2( position.x,-position.y)/uSize;`;
          const fragmentShader1 = `varying vec2 vUv;
                uniform float uTime;
                void main() {`;
          const fragmentShader2 = `#include <dithering_fragment> 
                 gl_FragColor.rgb=gl_FragColor.rgb+mix(vec3(0,0.5,0.5),vec3(1,1,0),vUv.y);`;

          material.onBeforeCompile = (shader, render) => {
            this.shaders.push(shader);
            shader.uniforms.uSize = { value: 50 };
            // shader.uniforms.uTime = { value: 0 };
            shader.vertexShader = shader.vertexShader.replace('void main() {', vertexShader1);
            shader.vertexShader = shader.vertexShader.replace(
              '#include <fog_vertex>',
              vertexShader2
            );
            shader.fragmentShader = shader.fragmentShader.replace('void main() {', fragmentShader1);
            shader.fragmentShader = shader.fragmentShader.replace(
              '#include <dithering_fragment>',
              fragmentShader2
            );
          };
          pm.onBeforeCompile = (shader, render) => {
            this.shaders.push(shader);
            shader.uniforms.uSize = { value: 50 };
            // shader.uniforms.uTime = { value: 0 };
            shader.vertexShader = shader.vertexShader.replace('void main() {', vertexShader1);
            shader.vertexShader = shader.vertexShader.replace(
              '#include <fog_vertex>',
              vertexShader3
            );
            shader.fragmentShader = shader.fragmentShader.replace('void main() {', fragmentShader1);
            shader.fragmentShader = shader.fragmentShader.replace(
              '#include <dithering_fragment>',
              fragmentShader2
            );
          };
        }
      }

      var myEarth = new MyEarth();
      window.myEarth = myEarth;
      myEarth.initThree(document.getElementById('canvas'));
      myEarth.createChart({});
    </script>
  </body>
</html>
